home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari Mega Archive 1
/
Atari Mega Archive - Volume 1.iso
/
mint
/
editors
/
mjovesrc.zoo
/
io.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-04
|
31KB
|
1,550 lines
/***************************************************************************
* This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne. JOVE *
* is provided to you without charge, and with no warranty. You may give *
* away copies of JOVE, including sources, provided that this notice is *
* included in all the files. *
***************************************************************************/
#include "jove.h"
#include "list.h"
#include "fp.h"
#include "termcap.h"
#include "ctype.h"
#include "disp.h"
#include "scandir.h"
#ifdef IPROCS
# include <signal.h>
#endif
#ifdef MAC
# include "mac.h"
#else
# include <sys/stat.h>
#endif
#ifdef UNIX
# include <sys/file.h>
#endif
#ifdef MSDOS
# include <fcntl.h>
# include <io.h>
# include <direct.h>
# include <dos.h>
#endif /* MSDOS */
#ifdef MiNT
#include <mintbind.h>
#endif
#include <errno.h>
private struct block
*lookup proto((int /* promoted short */));
private char
#if defined(MSDOS) || defined(MiNT)
*fixpath proto((char *)),
#endif
*getblock proto((daddr, bool));
private bool
f_getputl proto((struct line *line,struct FileStruct *fp));
private void
#if defined(MSDOS) || defined(MiNT)
abspath proto((char *, char *)),
#endif /* MSDOS || MiNT */
file_backup proto((char *fname));
#if defined(MSDOS) || defined(MiNT)
private int
Dchdir proto((char *));
#endif
long io_chars; /* number of chars in this open_file */
int io_lines; /* number of lines in this open_file */
#ifdef pdp11
char *iobuff,
*genbuf,
*linebuf;
#else
char iobuff[LBSIZE],
genbuf[LBSIZE],
linebuf[LBSIZE];
#endif
#ifdef BACKUPFILES
bool BkupOnWrite = OFF;
#endif
#if !defined(MSDOS) && !defined(MiNT)
#define Dchdir(to) chdir(to)
#endif
#ifdef MSDOS
private int /* chdir + drive */
Dchdir(to)
char *to;
{
unsigned d, dd, n;
if (to[1] == ':') {
d = CharUpcase(to[0]) - 'A';
/* ??? only 16 drives? */
if (d >= 16)
complain("invalid drive");
_dos_getdrive(&dd);
if (dd != d)
_dos_setdrive(d, &n);
if (to[2] == '\0') {
/* ??? Is this correct? DHR
* Current path on this drive might not be the root.
*/
return 0;
}
}
return chdir(to);
}
#endif /* MSDOS */
#ifdef MiNT
private int /* chdir + drive */
Dchdir(to)
char *to;
{
int d, dd;
if (to[1] == ':') {
d = CharUpcase(to[0]) - 'A';
dd = Dgetdrv();
if (dd != d)
Dsetdrv(d);
}
if ((to[2] == '\0') || ((to[2] == '/') && (to[3] == '\0')))
return chdir("\\");
return chdir(to);
}
#endif /* MiNT */
#if defined(MSDOS) || defined(MiNT)
private char *
fixpath(p)
char *p;
{
char *pp = p;
while (*p) {
if (*p == '\\')
*p = '/';
p++;
}
return strlwr(pp);
}
#endif /* MiNT || MSDOS */
#ifdef MSDOS
private void
abspath(so, dest)
char *so, *dest;
{
char cwd[FILESIZE], cwdD[3], cwdDIR[FILESIZE], cwdF[9], cwdEXT[5],
soD[3], soDIR[FILESIZE], soF[9], soEXT[5];
char *drive, *path;
_splitpath(fixpath(so), soD, soDIR, soF, soEXT);
getcwd(cwd, FILESIZE);
if (*soD != '\0') {
Dchdir(soD); /* this is kinda messy */
getcwd(cwdDIR, FILESIZE); /* should probably just */
Dchdir(cwd); /* call DOS to do it */
strcpy(cwd, cwdDIR);
}
(void) fixpath(cwd);
if (cwd[strlen(cwd)-1] != '/')
strcat(cwd, "/x.x"); /* need dummy filename */
_splitpath(fixpath(cwd), cwdD, cwdDIR, cwdF, cwdEXT);
drive = (*soD == '\0') ? cwdD : soD;
if (*soDIR != '/')
path = strcat(cwdDIR, soDIR);
else
path = soDIR;
_makepath(dest, drive, path, soF, soEXT);
fixpath(dest); /* can't do it often enough */
}
#endif /* MSDOS */
#ifdef MiNT
#define MAXPATHLEN 128
#define FILENAMELEN 13
#ifndef NULL
#define NULL (char *)0
#endif
#define lastchar(s) (*(s + strlen(s) - 1))
#define isslash(c) ((c) == '/')
#define isdrive(D) ((strlen(D) == 2) && (lastchar(D) == ':'))
private void
abspath(char *rel_path, char *abs_path)
{
char save_dir[MAXPATHLEN];
char f_name[FILENAMELEN];
char *c_ptr;
getcwd(save_dir, MAXPATHLEN);
if (chdir(rel_path) != -1) {
getcwd(abs_path, MAXPATHLEN);
chdir(save_dir);
return;
}
c_ptr = strrchr(rel_path, '/');
if (!c_ptr) {
if (isdrive(rel_path)) {
strcpy(abs_path, rel_path);
strcat(abs_path, "/");
return;
}
strcpy(abs_path, save_dir); /* a file name, with no */
if (!isslash(lastchar(abs_path))) /* path spec */
strcat(abs_path, "/");
strcat(abs_path, rel_path);
return;
}
strncpy(f_name, c_ptr + 1, FILENAMELEN);
*c_ptr = '\0';
if (chdir(rel_path) != -1) {
getcwd(abs_path, MAXPATHLEN);
if (!isslash(lastchar(abs_path)))
strcat(abs_path, "/");
strcat(abs_path, f_name);
strcat(rel_path, "/");
strcat(rel_path, f_name);
chdir(save_dir);
return;
}
abs_path[0] = (char)NULL;
return;
}
#endif /* MiNT */
void
close_file(fp)
File *fp;
{
if (fp) {
if (fp->f_flags & F_TELLALL)
add_mess(" %d lines, %D characters.",
io_lines,
io_chars);
f_close(fp);
}
}
/* Write the region from line1/char1 to line2/char2 to FP. This
never CLOSES the file since we don't know if we want to. */
bool EndWNewline = 1;
void
putreg(fp, line1, char1, line2, char2, makesure)
register File *fp;
Line *line1,
*line2;
int char1,
char2;
bool makesure;
{
register int c;
register char *lp;
if (makesure)
(void) fixorder(&line1, &char1, &line2, &char2);
while (line1 != line2->l_next) {
lp = lcontents(line1) + char1;
if (line1 == line2) {
fputnchar(lp, (char2 - char1), fp);
io_chars += (char2 - char1);
} else {
while ((c = *lp++) != '\0') {
jputc(c, fp);
io_chars += 1;
}
}
if (line1 != line2) {
io_lines += 1;
io_chars += 1;
#ifdef MSDOS
jputc('\r', fp);
#endif /* MSDOS */
jputc('\n', fp);
}
line1 = line1->l_next;
char1 = 0;
}
flushout(fp);
}
private void
dofread(fp)
register File *fp;
{
char end[LBSIZE];
bool xeof;
Line *savel = curline;
int savec = curchar;
strcpy(end, linebuf + curchar);
xeof = f_gets(fp, linebuf + curchar, (size_t) (LBSIZE - curchar));
SavLine(curline, linebuf);
while(!xeof) {
curline = listput(curbuf, curline);
xeof = f_getputl(curline, fp);
}
getDOT();
linecopy(linebuf, (curchar = strlen(linebuf)), end);
SavLine(curline, linebuf);
IFixMarks(savel, savec, curline, curchar);
}
void
read_file(file, is_insert)
char *file;
bool is_insert;
{
Bufpos save;
File *fp;
if (!is_insert)
curbuf->b_ntbf = NO;
fp = open_file(file, iobuff, F_READ, NO, NO);
if (fp == NULL) {
if (!is_insert && errno == ENOENT)
s_mess("(new file)");
else
s_mess(IOerr("open", file));
return;
}
if (!is_insert) {
set_ino(curbuf);
set_arg_value((fp->f_flags & F_READONLY)? 1 : 0);
TogMinor(ReadOnly);
}
DOTsave(&save);
dofread(fp);
if (is_insert && io_chars > 0) {
modify();
set_mark();
}
SetDot(&save);
getDOT();
close_file(fp);
}
void
SaveFile()
{
if (IsModified(curbuf)) {
if (curbuf->b_fname == NULL)
WriteFile();
else {
filemunge(curbuf->b_fname);
chk_mtime(curbuf, curbuf->b_fname, "save");
file_write(curbuf->b_fname, NO);
}
} else
message("No changes need to be written.");
}
char *HomeDir; /* home directory */
size_t HomeLen; /* length of home directory string */
private List *DirStack = NULL;
#define dir_name(dp) ((char *) list_data((dp)))
#define PWD_PTR (list_data(DirStack))
#define PWD ((char *) PWD_PTR)
char *
pwd()
{
return (char *) PWD_PTR;
}
char *
pr_name(fname, okay_home)
char *fname;
int okay_home;
{
int n;
if (fname != NULL) {
n = numcomp(fname, PWD);
if ((PWD[n] == '\0') && /* Matched to end of PWD */
(fname[n] == '/'))
return fname + n + 1;
if (okay_home && strcmp(HomeDir, "/") != 0
&& strncmp(fname, HomeDir, HomeLen) == 0
&& fname[HomeLen] == '/')
{
static char name_buf[100];
swritef(name_buf, sizeof(name_buf),
"~%s", fname + HomeLen);
return name_buf;
}
}
return fname;
}
void
Chdir()
{
char dirbuf[FILESIZE];
#ifdef MSDOS
fmask = 0x10;
#endif
(void) ask_file((char *)NULL, PWD, dirbuf);
#ifdef MSDOS
fmask = 0x13;
#endif
if (Dchdir(dirbuf) == -1)
{
s_mess("cd: cannot change into %s.", dirbuf);
return;
}
UpdModLine = YES;
setCWD(dirbuf);
prCWD();
#ifdef MAC
Bufchange = YES;
#endif
}
#ifdef UNIX
#